package top.continew.minithreadpool.ui.commonUi;

import top.continew.minithreadpool.concurrent.ThreadPool;
import top.continew.minithreadpool.concurrent.ThreadPoolExecutor;
import top.continew.minithreadpool.concurrent.ThreadPoolFactory;
import top.continew.minithreadpool.factory.DefaultThreadFactory;
import top.continew.minithreadpool.policy.AbortPolicy;

import javax.swing.*;
import java.awt.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;

public class ThreadPoolVisualizer extends JFrame {
    private ThreadPoolExecutor threadPool;
    private Timer timer;

    // UI 组件
    private JLabel coreSizeLabel;
    private JLabel maxSizeLabel;
    private JLabel activeThreadsLabel;
    private JLabel queueSizeLabel;
    private JLabel completedTasksLabel;
    private JLabel stateLabel;

    private TaskQueuePanel taskQueuePanel;
    private JTextArea logArea;

    private JButton startButton;
    private JButton stopButton;
    private JButton submitButton;

    private JSpinner taskCountSpinner;
    private JSpinner corePoolSizeSpinner;
    private JSpinner maxPoolSizeSpinner;

    public ThreadPoolVisualizer() {
        super("线程池教学工具");
        setSize(1000, 700);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLayout(new BorderLayout());

        // 初始化线程池
        threadPool = ThreadPoolFactory.createFixedThreadPool(4);

        // 创建UI组件
        createUI();

        // 启动状态更新定时器
        startStatusTimer();
    }

    private void createUI() {
        // 顶部控制面板
        JPanel controlPanel = new JPanel(new GridLayout(1, 3));

        // 线程池配置面板
        JPanel configPanel = new JPanel(new GridLayout(4, 2, 5, 5));
        configPanel.setBorder(BorderFactory.createTitledBorder("线程池配置"));

        JLabel coreSizeText = new JLabel("核心线程数:");
        corePoolSizeSpinner = new JSpinner(new SpinnerNumberModel(4, 1, 20, 1));
        JLabel maxSizeText = new JLabel("最大线程数:");
        maxPoolSizeSpinner = new JSpinner(new SpinnerNumberModel(4, 1, 20, 1));

        configPanel.add(coreSizeText);
        configPanel.add(corePoolSizeSpinner);
        configPanel.add(maxSizeText);
        configPanel.add(maxPoolSizeSpinner);

        // 状态面板
        JPanel statusPanel = new JPanel(new GridLayout(2, 3, 5, 5));
        statusPanel.setBorder(BorderFactory.createTitledBorder("线程池状态"));

        JLabel activeThreadsText = new JLabel("活跃线程:");
        activeThreadsLabel = new JLabel("0");
        JLabel queueSizeText = new JLabel("队列大小:");
        queueSizeLabel = new JLabel("0");
        JLabel completedTasksText = new JLabel("完成任务:");
        completedTasksLabel = new JLabel("0");
        JLabel stateText = new JLabel("状态:");
        stateLabel = new JLabel("运行中");

        statusPanel.add(activeThreadsText);
        statusPanel.add(activeThreadsLabel);
        statusPanel.add(queueSizeText);
        statusPanel.add(queueSizeLabel);
        statusPanel.add(completedTasksText);
        statusPanel.add(completedTasksLabel);
        statusPanel.add(stateText);
        statusPanel.add(stateLabel);
        statusPanel.add(new JLabel()); // 占位符

        // 控制按钮面板
        JPanel buttonPanel = new JPanel(new GridLayout(4, 1, 5, 5));
        buttonPanel.setBorder(BorderFactory.createTitledBorder("控制"));

        startButton = new JButton("启动线程池");
        stopButton = new JButton("停止线程池");
        submitButton = new JButton("提交任务");
        JButton resizeButton = new JButton("调整线程池");

        startButton.addActionListener(e -> startThreadPool());
        stopButton.addActionListener(e -> stopThreadPool());
        submitButton.addActionListener(e -> submitTasks());
        resizeButton.addActionListener(e -> resizeThreadPool());

        buttonPanel.add(startButton);
        buttonPanel.add(stopButton);
        buttonPanel.add(submitButton);
        buttonPanel.add(resizeButton);

        // 将三个面板添加到控制面板
        controlPanel.add(configPanel);
        controlPanel.add(statusPanel);
        controlPanel.add(buttonPanel);

        // 任务队列面板
        BlockingQueue<Runnable> queue = threadPool.getQueue();
        taskQueuePanel = new TaskQueuePanel(queue);

        // 任务提交面板
        JPanel taskPanel = new JPanel();
        taskPanel.setBorder(BorderFactory.createTitledBorder("任务提交"));

        JLabel taskCountLabel = new JLabel("任务数量:");
        taskCountSpinner = new JSpinner(new SpinnerNumberModel(10, 1, 100, 1));

        taskPanel.add(taskCountLabel);
        taskPanel.add(taskCountSpinner);

        // 日志区域
        JPanel logPanel = new JPanel(new BorderLayout());
        logPanel.setBorder(BorderFactory.createTitledBorder("执行日志"));

        logArea = new JTextArea();
        logArea.setEditable(false);
        JScrollPane scrollPane = new JScrollPane(logArea);

        logPanel.add(scrollPane, BorderLayout.CENTER);

        // 添加所有组件到主窗口
        add(controlPanel, BorderLayout.NORTH);
        add(taskQueuePanel, BorderLayout.CENTER);
        add(taskPanel, BorderLayout.SOUTH);
        add(logPanel, BorderLayout.EAST);
    }

    private void startStatusTimer() {
        timer = new Timer(50, e -> {
            updateStatus();
            taskQueuePanel.refresh();
        });
        timer.start();
    }

    private void updateStatus() {
        // 更新状态标签
        activeThreadsLabel.setText(String.valueOf(threadPool.getActiveCount()));
        queueSizeLabel.setText(String.valueOf(threadPool.getQueue().size()));
        completedTasksLabel.setText(String.valueOf(threadPool.getCompletedTaskCount()));

        // 更新状态标签
        if (threadPool.isShutdown()) {
            stateLabel.setText("已关闭");
        } else {
            stateLabel.setText("运行中");
        }
    }

    private void startThreadPool() {
        if (threadPool != null && !threadPool.isShutdown()) {
            log("线程池已在运行中");
            return;
        }

        int coreSize = (Integer) corePoolSizeSpinner.getValue();
        int maxSize = (Integer) maxPoolSizeSpinner.getValue();

        threadPool = new ThreadPool(
                coreSize, maxSize, 0L, TimeUnit.MILLISECONDS,
                new LinkedBlockingQueue<>(100),
                new DefaultThreadFactory(),
                new AbortPolicy()
        );

        log("线程池已启动 (核心线程: " + coreSize + ", 最大线程: " + maxSize + ")");
    }

    private void stopThreadPool() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池已关闭或未启动");
            return;
        }

        threadPool.shutdown();
        log("线程池关闭中...");

        // 在后台等待线程池关闭
        new Thread(() -> {
            try {
                threadPool.awaitTermination(5, TimeUnit.SECONDS);
                log("线程池已完全关闭");
            } catch (InterruptedException ex) {
                log("线程池关闭被中断");
            }
        }).start();
    }

    private void resizeThreadPool() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池未启动，请先启动线程池");
            return;
        }

        int newCoreSize = (Integer) corePoolSizeSpinner.getValue();
        int newMaxSize = (Integer) maxPoolSizeSpinner.getValue();

        threadPool.setCorePoolSize(newCoreSize);
        threadPool.setMaximumPoolSize(newMaxSize);

        log("线程池已调整 (新核心线程: " + newCoreSize + ", 新最大线程: " + newMaxSize + ")");
    }

    private void submitTasks() {
        if (threadPool == null || threadPool.isShutdown()) {
            log("线程池未启动或已关闭，无法提交任务");
            return;
        }

        int taskCount = (Integer) taskCountSpinner.getValue();
        log("提交 " + taskCount + " 个任务");

        for (int i = 0; i < taskCount; i++) {
            final int taskId = i;
            threadPool.execute(() -> {
                String threadName = Thread.currentThread().getName();
                log("任务 " + taskId + " 开始执行 (" + threadName + ")");

                try {
                    // 模拟任务执行时间 (1-3秒)
                    int duration = 1000 + (int)(Math.random() * 2000);
                    Thread.sleep(duration);

                    log("任务 " + taskId + " 完成 (" + threadName + ")");
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                    log("任务 " + taskId + " 被中断 (" + threadName + ")");
                }
            });
        }
    }

    private void log(String message) {
        SwingUtilities.invokeLater(() -> {
            logArea.append(message + "\n");
            // 自动滚动到最后一行
            logArea.setCaretPosition(logArea.getDocument().getLength());
        });
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            ThreadPoolVisualizer visualizer = new ThreadPoolVisualizer();
            visualizer.setVisible(true);
        });
    }
}
